/**
 * README
 * 
 * Modificacion de la biblioteca jWave disponible en http://code.google.com/p/jwave/
 * Convertidos los tipos de datos a float para agilizar el tratamiendo de grandes arrays de datos
 * como son los que se tratan en analisis genomicos.
 * Los autores originales de las funciones y del código de la biblioteca cuando fue seleccionada en
 * Abril de 2012 eran:
 *        Christian Scheiblich
 *        Thomas Leduc
 *        sashi
 *        Pol Kennel
 *        Thomas Haider
 *        
 * Por supuesto, todo el merito, honores y demas menciones sobre esta adaptacion les corresponden a ellos
 * y nada mas que a ellos.
 * 
 * 
 * This is a modified version of jWave, available in http://code.google.com/p/jwave/
 * It has been replace the double datatype with float for performance reasons in very big arrays used in
 * bioinformatics like genomic analysis.
 * Original authors of functions and the library when it has been selected in 2012's April were:
 *        Christian Scheiblich
 *        Thomas Leduc
 *        sashi
 *        Pol Kennel
 *        Thomas Haider
 *        
 * Of course, all the merits and mentions about this adaptation have corresponded to them.
 * 
 */

package ev.maths;

import ev.maths.handlers.BasicTransform;
import ev.maths.handlers.TransformInterface;
import ev.maths.handlers.WaveletTransform;
import ev.maths.Complex;

/**
 * Clase base para transformadas como DiscreteFourierTransform,
 * FastWaveletTransform, y WaveletPacketTransform.
 * 
 * @date 01.08.2012
 * @author Enrique Vázquez de Luis
 */
public class Transform {

  /**
   * Transformada que se va a aplicar
   */
  protected TransformInterface _transform;
  
  /**
   * Constructor. Necesita un objeto de transformada
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param transform Objeto de transformada
   */
  public Transform( TransformInterface transform ) {
    _transform = transform;
  } // Transform
  
  /**
   * Constructor. Necesita la transformada a aplicar y el número de iteraciones.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param transform Objeto de transformada
   * @param iteration Número de iteraciones.
   */
  public Transform( TransformInterface transform, int iteration ) {
    if( transform instanceof WaveletTransform ) {
      _transform = transform;
      ( (WaveletTransform)_transform ).set_iteration( iteration );
    } else {
      throw new IllegalArgumentException(
          "No se puede utilizar la transformada :" + transform.getClass( )
              + " con el nivel de descomposición especificado ;"
              +	" utilice el constructor Transform( TransformI transform )." );
    }
  } // Transform

  /**
   * Realiza la transformada de la función en el tiempo
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param arrTime Valores de la función en el tiempo.
   * @return Valores de la función en frecuencia.
   */
  public float[ ] forward( float[ ] arrTime ) {
    return _transform.forward( arrTime );
  } // forward

  /**
   * Realiza la transformada inversa de la función en la frecuencia
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param arrFreq Valores de la función en la frecuencia.
   * @return Valores de la función en el dominio del tiempo.
   */
  public float[ ] reverse( float[ ] arrFreq ) {
    return _transform.reverse( arrFreq );
  } // reverse


  /**
   * Realiza la transformada desde el dominio del tiempo al de la energía
   * o al de Hilbert del array dado dependiendo del algoritmo de transformación
   * utilizado en la instanciación.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param arrTime Coeficientres de una dimensión del dominio del tiempo.
   * @return coeficientes de una dimensión del espacio de Hilbert o el dominio de la frecuencia.
   */
  public Complex[ ] forward( Complex[ ] arrTime ) {
    return ((BasicTransform)_transform).forward( arrTime );
  } // forward

  /**
   * Realiza la transformada inversa desde el dominio de Hilbert o el de la frecuencia
   * al dominio del tiempo del array dado utilizando para ello el algoritmo de transformación
   * utilizado para instanciar.
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param arrFreq Coeficientes de una dimensión del dominio de Hilbert o el de la frecuencia.
   * @return Coeficientes de 1 dimensión del dominio del tiempo.
   */
  public Complex[ ] reverse( Complex[ ] arrFreq ) {
    return ((BasicTransform)_transform).reverse( arrFreq );
  } // reverse
  
  /**
   * Realiza la transformada bidimensional
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param matrixFreq datos del dominio del tiempo
   * @return Coeficientes del espaciode Hilbert
   */
  public float[ ][ ] forward( float[ ][ ] matrixTime ) {
    return _transform.forward( matrixTime );
  } // forward

  /**
   * Realiza la transformada inversa bidimensional
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param matrixFreq datos del dominio de Hilbert
   * @return Coeficientes del espacio original
   */
  public float[ ][ ] reverse( float[ ][ ] matrixFreq ) {
    return _transform.reverse( matrixFreq );
  } // reverse

  /**
   * Realiza la transformada tridimensional
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param matrixFreq datos del dominio del tiempo
   * @return Coeficientes del espacio de Hilbert
   */
  public float[ ][ ][ ] forward( float[ ][ ][ ] spaceTime ) {
    return _transform.forward( spaceTime );
  } // forward

  /**
   * Realiza la transformada inversa tridimensional
   * 
   * @date 01.08.2012
   * @author Enrique Vázquez de Luis
   * @param matrixFreq datos del dominio de Hilbert
   * @return Coeficientes del espacio original
   */
  public float[ ][ ][ ] reverse( float[ ][ ][ ] spaceFreq ) {
    return _transform.reverse( spaceFreq );
  } // reverse
  
} // class
